/*****************************************************************************
*    Ali Corp. All Rights Reserved. 2007 Copyright (C)
*
*    File:    slot.S
*
*    Description:    This file contains all code in standby mode.
*    History:
*           Date            Athor        Version          Reason
*	    ============	=============	=========	=================
*	1.	05.22.2007       zhaojian tang      Ver 0.1    Create file.
*	2.	28.03.2008		 Victor				Ver	0.2	 Support 16515 VFD panel
*****************************************************************************/
#include <hal/mips.h>
#include <sys_config.h>

#define TIMER_COMPARE_1S	(27000000 / 4)

//#define DIRECT_GPIO_POWER_ON		39

#ifndef	PAN_KEY_STANDBY
#define PAN_KEY_STANDBY			0xFFFF0008
#endif
#ifndef IRP_KEY_STANDBY
#define IRP_KEY_STANDBY			0x807fc03f
#endif
#ifndef IRP_KEY_STANDBY2
#define IRP_KEY_STANDBY2		0x60df708f
#endif

#define HAL_GPIO_DI_REG		0xb8000050
#define HAL_GPIO_DO_REG		0xb8000054
#define HAL_GPIO_DIR_REG       0xb8000058

#define HAL_GPIO1_DI_REG		0xb80000d0
#define HAL_GPIO1_DO_REG	0xb80000d4
#define HAL_GPIO1_DIR_REG	0xb80000d8

#define HAL_GPIO2_DI_REG		0xb80000e4
#define HAL_GPIO2_DO_REG	0xb80000e8
#define HAL_GPIO2_DIR_REG	0xb80000ec

#define HAL_GPIO3_DI_REG		0xb80000f0
#define HAL_GPIO3_DO_REG	0xb80000f4
#define HAL_GPIO3_DIR_REG	0xb80000f8


# MACRO: bin2ascii#define PAN_KEY_STANDBY			0xFFFF0008
#  reg b1: Input binary data.
#  reg d1: Output BCD code data.
# Internal:
#  t0: ;
#  t1: Primary higher 4 digital;
#  t2: Lower 4 bit digital;
#  t3: ;
#
		.macro	bin2ascii b1,d1
		andi	t0, \b1, 0xf0;
		srl		t0, 4;					# 6bits->2bits higher
		srl		t1, t0, 1;
		addu	t1, t0;					# Get the base: 00b=>0d, 01b=>1d, 10b=>3d, 11b=>4d
		sll		t2, t1, 3;
		sll		t3, t1, 1;
		addu	t3, t2;					# 10X: 0=>0, 1=>10, 2=>20, etc...
		subu	t2, \b1, t3;			# Get draft lower value to t2
		li		t0, 10;
		blt		t2, t0, 11f;			# If lower 4bits<10, finished
		nop
		addiu	t1, 1;					# Else higher+1, and lower-10.
		sub		t2, t0;
		blt		t2, t0, 11f;			# If lower 4bits<10, finished
		nop
		addiu	t1, 1;					# Else higher+1, and lower-10.
		sub		t2, t0;
11:		sll		t1, 4;
		or		\d1, t1, t2;
		.endm

# MACRO: get_led_array(reg dr)
#  reg dr: load led_array to dr.
#
		.macro	get_led_array dr
		la		\dr, led_array
		or		\dr, \dr, 0xa0000000	# ensure not use D-cache to load variable
		.endm


# MACRO: get_fp_power_key(reg dr)
#  reg dr: load fp power key to dr.
#
		.macro	get_fp_power_key dr
		li		\dr, PAN_KEY_STANDBY
		.endm


# MACRO: get_pan_hw_info(reg dr)
#  reg dr: load pan_hw_info to dr.
#
		.macro	get_pan_hw_info dr
		la		\dr, pan_hw_info
		or		\dr, \dr, 0xa0000000	# ensure not use D-cache to load variable
		.endm


# MACRO: get_ir_power_key(reg dr)
#  reg dr: load ir power key to dr.
#
		.macro	get_ir_power_key dr
		li		\dr, IRP_KEY_STANDBY
		.endm

		.macro	get_ir_power_key2 dr
		li		\dr, IRP_KEY_STANDBY2
		.endm

		.macro	get_led_dot_bmp dr
		li		\dr, 0xfe
		.endm

		.macro	gettimerdata dr
		li		t1, 0x80000700
		lw		\dr, 0(t1)
		.endm
		
		.macro	settimerdata sr
		li		t1, 0x80000700			# Set REF head address
		sw		\sr,0(t1)	
		.endm


#--------------------------------------------------------------------
#
#   Function_Name: sys_preboot
#     This function used only for board dedicated issue patch, just as
#     turn off LED GPIO, if you want do other patch about chipset,
#     please added into _Init_Chipset in boot.S.
#--------------------------------------------------------------------
		.globl  sys_preboot
		.ent	sys_preboot
		.set noreorder
sys_preboot:
		jr		ra
		nop
		.set 	reorder
		.end	sys_preboot



		.globl  sys_prestandby
		.ent	sys_prestandby
		.set	noreorder
sys_prestandby:
		move	k0, ra
		nop
		jal		ini_ir					# Init IR
		nop
		move 	ra, k0
		nop		
		move	k0, ra
		nop
#if defined(PANEL_16515_VFD)
		li		t0, 0x80000760
		li		a0, 0x16515
		sw		a0, (t0)
		jal		nec_16312_hw_init
		nop
#elif  defined(PANEL_16312_VFD)
		li		t0, 0x80000760
		li		a0, 0x16312
		sw		a0, (t0)
		jal		nec_16312_hw_init
#else	
		get_pan_hw_info a0
		jal 	pan_common_gpio_init_cp_hw
		li		a1, 1
		move	s8, zero				# Preset led_buff(s8) as 0
		get_pan_hw_info t8
		lw		t0, (t8)				# Check kb_type
		andi	t0, 0x02
		bne 	t0, zero, 1f
		nop
		lb		a0, 16(t8)
		jal 	pan_common_gpio_set_bit_cp_hw	# Set STANDBY to valid status
		li		a1, 1
		b		2f
		nop
1:
		lw		t0, 16(t8)				# Setup led_buff to invalidate status but STANDBY
		li		t1, 0
		li		t2, 32
ledbufbit:
		srl 	t3, t0, 2				# Get the ledbit position
		andi	t3, 0x7
		li		t4, 1
		sll 	t4, t3					# Bit mask
		andi	t3, t0, 1				# Check bit active status
		bne 	t3, zero, ledposbit
		nop
		or		s8, t4					# Merge this bit
ledposbit:
		addi	t1, 8
		srl 	t0, t0, t1				# Next PIN
		bne 	t1, t2, ledbufbit
		nop
		andi	s8, 0xff
2:
#endif
		move	ra, k0
		
#if (STANDBY_PANEL_SHOW_WAHT == STANDBY_PANEL_SHOW_TIMER)
		li		t0, (0x1f<<12)			# Hour in ASCII
		and 	v0, t0, s5
		srl 	v0, 12
		bin2ascii v0, t5
		sll 	t5, 8
		li		t0,(0x3f<<6)			# Minute in ASCII
		and 	v0, t0, s5
		srl 	v0, 6
		bin2ascii v0, t4
		or		s6, t4, t5
		
		settimerdata s6

#elif (STANDBY_PANEL_SHOW_WAHT == STANDBY_PANEL_SHOW_OFF)
		li		s6, 0xabbf				# "OFF " index
#elif (STANDBY_PANEL_SHOW_WAHT == STANDBY_PANEL_SHOW_BLANK)
		li		s6, 0xffff				# "    " index
#endif
3:
		jr		ra
		nop
		.set reorder
		.end sys_prestandby


		.globl	sys_poststandby
		.ent	sys_poststandby
		.set noreorder
sys_poststandby:
		move	k1, ra

#if !(defined(PANEL_16312_VFD) || defined(PANEL_16515_VFD))
		get_pan_hw_info a0
		jal 	pan_common_gpio_init_cp_hw
		li		a1, 0
		get_pan_hw_info a1				# Set STANDBY to invalid status
		lb		a0, 16(a1)
		jal 	pan_common_gpio_set_bit_cp_hw
		li		a1, 0
#endif
		move	ra, k1
		jr		ra
		nop
		.set reorder
		.end sys_poststandby
		


		.globl	sys_standby_process
		.ent	sys_standby_process
sys_standby_process:		
		.set	noreorder
		mfc0	t0, C0_COUNT			# Check scan or not
		li		t1, (TIMER_COMPARE_1S>>8)	# 1/256 second per LED
		subu	       t2, s4, t0
		bgtu	       t2, t1, real_scan
		nop
		li		v0,0
		jr		ra
		nop
real_scan:
		addu	s4, t1					# 1/256 second per LED
		move	k0, ra
#ifdef DIRECT_GPIO_POWER_ON
		li		t3,DIRECT_GPIO_POWER_ON
//		li		t3,39
		li		t2, 95
		li 		t1,0x01
		sub 	t2, t3
		beqz	t2, 3f
		nop
		sllv t1,t1,t3		
		andi  t2, t3, 0x40
		beqz  t2, small64
		nop
		lw		t2, HAL_GPIO2_DIR_REG//0xd8(t0)
		not 	t3, t1
		and 	t2, t3
		sw		t2, HAL_GPIO2_DIR_REG//0xd8(t0)
		lw		t2, HAL_GPIO2_DI_REG//0xd0(t0)
		and t2, t1
		beqz	t2, out_process
		nop 	
		b		3f
		nop
small64:
		andi  t2, t3, 0x20
		beqz  t2, small32
		nop
		lw		t2, HAL_GPIO1_DIR_REG//0xd8(t0)
		not 	t3, t1
		and 	t2, t3
		sw		t2, HAL_GPIO1_DIR_REG//0xd8(t0)
		lw		t2, HAL_GPIO1_DI_REG//0xd0(t0)
		and t2, t1
		beqz	t2, out_process
		nop 	
		b		3f
		nop
small32:
		lw		t2, HAL_GPIO_DIR_REG//0xd8(t0)
		not 	t3, t1
		and 	t2, t3
		sw		t2, HAL_GPIO_DIR_REG//0xd8(t0)
		lw		t2, HAL_GPIO_DI_REG//0xd0(t0)
		and t2, t1
		beqz	t2, out_process
		nop 	
		b		3f
		nop
#endif		
#if (STANDBY_PANEL_SHOW_WAHT == STANDBY_PANEL_SHOW_TIMER)
		gettimerdata t0
		move 	s6,t0
#endif

#if !(defined(PANEL_16312_VFD) || defined(PANEL_16515_VFD))

# We just display one LED each times, keeping show when exit function
		get_pan_hw_info a0
		lw		t3, (a0)
		srl 	t0, t3, 8
		andi	t0, 0x0f				# Inc and get current COM number
		srl 	t2, s6, 24
		addi	t2, 1
		bne 	t2, t0, 1f
		nop
		move	t2, zero
1:
		sll 	s6, 8					# Set new LED ID
		srl 	s6, 8
		sll 	t0, t2, 24
		or		s6, t0
#if (STANDBY_PANEL_SHOW_WAHT == STANDBY_PANEL_SHOW_TIMER)
		settimerdata s6
#endif
		sll 	t0, t2, 2				# Get current LED COM index
		li		t1, 0x0c
		subu	t1, t0
		bgez	t1, dot_pos 			# If dot position > 3, LED bitmap should be '.'
		li		t0, 12
		b		dot_end
		nop

dot_pos:
		srl 	t0, s6, t1
		andi	t0, 0x0f				# Get current LED bitmap offset
dot_end:
		get_led_array t4
		addu	t1, t4, t0
		lbu 	a2, (t1)				# Get current LED bitmap

dot_set:
		srl 	t0, t3, 12				# Check the dot LED
		andi	t0, 0x0f
		bne 	t0, t2, 2f
		nop
		lb		t0, 12(t4)				# Get the ":" mask map
		srl 	t1, s6, 16
		and 	t0, t1
		xor 	a2, t0
2:
		sll 	a2, 8
		or		a2, s8
		jal 	pan_common_scan_cp_hw
		srl 	a1, s6, 24
		get_fp_power_key t0 			# Check power on key
		bne 	t0, v0, 3f
		nop
#else
		get_led_array t4
		li		t2, 0
		li		t3, 16
		li		t7, 0x80000720
		srl 	t1, s6, 16
1:		srlv 	t0, s6, t2
		andi	t0, 0x0f
		sll		t0, 1
		add		t5, t4, t0
		lbu		t6, (t5)
		sb		t6, (t7)
		addiu	t5, 1
		addiu	t7, 1
		lbu		t6, (t5)
		and		a0, t3, 0x08
		beqz	a0, 2f
		nop
		xor		a1, t1, 0xff
		beqz	a1, 2f
		nop
		or		t6, 0x80			
2:		sb		t6, (t7)
		addiu	t2, 4
		addiu	t3, -4
		addiu	t7, 2
		nop
		bnez	t3, 1b
		nop
	
		li		a3,	0x80000720
		li		a2,	0x1b
		jal		send_16312_command
		li		a0, 0xc0
		jal		check_key_16312
		nop
		li		t3, PAN_KEY_STANDBY
		bne		v0, t3, 3f
		nop 
#endif
		
out_process:
		li		s8, 0xdeadbead			# Set the flag about time to REF
		jal 	exit_standby			# Power key press, exit standby
		nop
3:
		move	ra, k0
		jr		ra
		nop
		.set reorder
		.end sys_standby_process


#define SYS_IC_NB_BASE_H		0xb800
#define SYS_IC_NB_EISR			0x30
#define SYS_IC_SB_IRC_BITIE 	0x80000
		.globl	sys_standby_exception
		.ent	sys_standby_exception
sys_standby_exception:	
		.set	noreorder
#if (SYS_CHIP_MODULE != ALI_S3601)
		la		t1, 3f					# Running in cache
		sll 	t1, 4
		srl 	t1, 4
		lui 	t0, 0x8000
		or		t1, t0
		jr		t1
		nop
#endif
3:
		lui 	t1,SYS_IC_NB_BASE_H
		lw		t2,SYS_IC_NB_EISR(t1)
		li		t0, SYS_IC_SB_IRC_BITIE
		and 	 t3,t2,t0				# IR interrupt?
		bnez	 t3,2f
		nop
		
		li		s8, 0xdeadbeef			# Set the flag about enter IC stanby again
		jal 	exit_standby
		nop
2:
		
		jal 	get_ir					# Get IR code
		nop
#if !(defined(PANEL_16312_VFD) || defined(PANEL_16515_VFD))		
		get_ir_power_key t1				# Check POWER remote key code
		beq		v0, t1, 3f

		get_ir_power_key2 t1
		bne		v0, t1, 4f

#else
		li		t1, IRP_KEY_STANDBY
		bne		v0, t1, 4f		
#endif		
		nop
3:		
		li		s8, 0xdeadbead			# Set the flag about time to REF
		jal 	exit_standby
		nop
4:
		nop
					nop
		.set mips3
		eret
		.set mips1
		nop
		nop
		.set reorder
		.end sys_standby_exception

#if !defined(PANEL_16515_VFD)
led_array:
			 /*  '0'   '1'   '2'   '3'*/
		.byte	0x03, 0x9f, 0x25, 0x0d
			 /*  '4'   '5'   '6'   '7'*/
		.byte	0x99, 0x49, 0x41, 0x1f
			 /*  '8'   '9'   'O'   'F'*/
		.byte	0x01, 0x09, 0x03, 0x71
			 /*  ':'   '-'   '_'   ' '*/
		.byte	0x01, 0xfd, 0xef, 0xff
#else


led_array:
			 /*     '0'         '1'         '2'         '3'  */
		.byte	0x31, 0x46, 0x10, 0x02, 0xd1, 0x45, 0xd1, 0x43
			 /*     '4'         '5'         '6'         '7'  */
		.byte	0xf0, 0x03, 0xe1, 0x43, 0xe1, 0x47, 0x11, 0x02
			 /*     '8'         '9'         'O'         'F'  */
		.byte	0xf1, 0x47, 0xf1, 0x43, 0x31, 0x46, 0xe1, 0x05
			 /*     ':'         '-'         '_'         ' '  */
		.byte	0x80, 0x00, 0xc0, 0x01, 0x00, 0x40, 0x00, 0x00

#endif
